package com.wyh.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.easemob.im.server.EMService;
import com.easemob.im.server.api.token.allocate.TokenProvider;
import com.wyh.common.constant.Constant;
import com.wyh.common.response.PageInfo;
import com.wyh.common.result.R;
import com.wyh.common.util.Md5Utils;
import com.wyh.common.util.RandomUtils;
import com.wyh.common.util.SnowFlakeGenerateIdWorker;
import com.wyh.common.util.StringUtil;
import com.wyh.entity.AdminUser;
import com.wyh.framework.redis.RedisCache;
import com.wyh.mapper.AdminUserMapper;
import com.wyh.request.AdminUserRequest;
import com.wyh.request.PasswordLoginRequest;
import com.wyh.request.VerifyCodeLoginRequest;
import com.wyh.service.IAdminUserService;
import com.wyh.vo.LoginVo;
import com.wyh.vo.UserVo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 用户管理业务层处理
 *
 * @author WangYuHang
 * @date 2024-03-03
 */
@Slf4j
@Service
@AllArgsConstructor
public class AdminUserServiceImpl implements IAdminUserService {

    private final AdminUserMapper baseMapper;

    @Autowired
    private final EMService emService;

    @Autowired
    private final RedisCache redisCache;

    @Autowired
    SnowFlakeGenerateIdWorker snowFlakeGenerateIdWorker;

    @Override
    public R<LoginVo> passwordLogin(PasswordLoginRequest loginRequest) {


        System.out.println(loginRequest);
        //校验手机号
        if (!StringUtils.isNotBlank(loginRequest.getPhoneInput())){
            return R.error("手机号不能为空");
        }
        if (!StringUtils.isNotBlank(loginRequest.getPasswordInput())){
            return R.error("密码不能为空");
        }

        //根据账号密码搜索用户
        LambdaQueryWrapper<AdminUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AdminUser::getPhone,loginRequest.getPhoneInput());
        try {
            queryWrapper.eq(AdminUser::getPassword,Md5Utils.getMd5(loginRequest.getPasswordInput()));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        AdminUser adminUser = baseMapper.selectOne(queryWrapper);
        if (adminUser==null){
            //用户不存在 账号密码错误
            return R.error("账号或密码错误");
        }


        if (adminUser.getStatus()==1){
            return R.error("用户已被封禁");
        }


        LoginVo loginVo = new LoginVo();
        BeanUtils.copyProperties(adminUser,loginVo);

        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(adminUser,userVo);

        //登录成功生成Token返回
        String userTokenWithInherit = emService.token().getUserTokenWithInherit(adminUser.getUserId());
        System.out.println("登陆者的token");
        System.out.println(userTokenWithInherit);


        loginVo.setUser(userVo);
        loginVo.setToken(userTokenWithInherit);
        //用户token
        redisCache.setCacheObject(Constant.USER_TOKEN_CACHE + adminUser.getUserId(), loginVo, 20, TimeUnit.MINUTES);

        return R.success(loginVo);
    }

    @Override
    public R<LoginVo> verifyCodeLogin(VerifyCodeLoginRequest verifyCodeLoginRequest) {
        return null;
    }

    /**
     * 注册用户
     * @param request param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> add(AdminUserRequest request) {
        //查找条件
        LambdaQueryWrapper<AdminUser> queryWrapper = new LambdaQueryWrapper<>();

        //先校验手机号是否已被使用
        if (StringUtils.isNotBlank(request.getPhone())){
            queryWrapper.eq(AdminUser::getPhone,request.getPhone());
            AdminUser adminUser = baseMapper.selectOne(queryWrapper);
            if (adminUser!=null){
                //手机号已经注册过了
                return R.error("手机号已经注册过了");
            }
        }
        //获取验证码
        String verifyCode = request.getVerifyCode();
        //假设验证码是12345
        String number = "12345";
        //String number = RandomUtils.getNumber(4);
      //  redisCache.setCacheObject("verify",number);
        //判断验证码是否一致
        if (!verifyCode.equalsIgnoreCase(number)){
            return R.error("验证码错误");
        }

        //注册新用户
        AdminUser entity =
                AdminUser.builder()
                         .phone(request.getPhone())
                         .nickname(request.getNickname()).build();

        //用户是否传入邀请码 若传入则绑定主播经济人关系
        if (!StringUtil.isEmpty(request.getInviteCode())){
            //清理之前的条件
            queryWrapper.clear();
            //绑定经济人与用户之间的关系
            if (StringUtils.isNotBlank(request.getInviteCode())){
                queryWrapper.eq(AdminUser::getInviteCode,request.getInviteCode());
            }
            AdminUser adminUser = baseMapper.selectOne(queryWrapper);
            if (adminUser==null){
                return R.error("邀请码错误");
            }
            //设置经纪人
            entity.setEconomicId(adminUser.getUserId());
        }



        String userId = getUserId(); //随机生成用户6位数字id
        String inviteCode = getInviteCode();//随机生成5位数字用户邀请码
        String liveRoomId = getLiveRoomId();//随机生成6位直播间id
        entity.setUserId(userId);
        entity.setInviteCode(inviteCode);
        entity.setLiveRoomId(liveRoomId);


        try {
            entity.setPassword(Md5Utils.getMd5(request.getPassword()));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }


        baseMapper.insert(entity);
        emService.user().create(entity.getUserId(),entity.getPassword());
        return R.success("注册成功！");
    }


    /**
     * 获取唯一直播间id
     * 并发情况下可能有两个人相同id
     * @return
     */
    public String getLiveRoomId(){
        //获取6位数直播间id
        AdminUser user = AdminUser.builder().build();
        LambdaQueryWrapper<AdminUser> wrapper = new LambdaQueryWrapper<>();
        String liveRoomId;
        while (true) {
            //生成直播间id
            liveRoomId = RandomUtils.getNumber(6);
            // 使用liveRoomId设置查询条件
            user.setLiveRoomId(liveRoomId);
            wrapper.eq(AdminUser::getLiveRoomId, liveRoomId);
            // 查询数据库中是否存在对应的用户
            AdminUser existingUser = baseMapper.selectOne(wrapper);
            // 如果不存在，则退出循环，inviteCode是唯一的
            if (existingUser == null) {
                break;
            }
            // 重置查询条件，以便下一次循环
            wrapper.clear();
        }
        return liveRoomId;
    }


    /**
     * 获取唯一邀请码
     * @return
     */
    public String getInviteCode(){
        //获取5位数邀请码
        AdminUser user = AdminUser.builder().build();
        LambdaQueryWrapper<AdminUser> wrapper = new LambdaQueryWrapper<>();
        String inviteCode;
        while (true) {
            //生成邀请码
            inviteCode = RandomUtils.getNumber(5);
            // 使用inviteCode设置查询条件
            user.setInviteCode(inviteCode);
            wrapper.eq(AdminUser::getInviteCode, inviteCode);
            // 查询数据库中是否存在对应的用户
            AdminUser existingUser = baseMapper.selectOne(wrapper);
            // 如果不存在，则退出循环，inviteCode是唯一的
            if (existingUser == null) {
                break;
            }
            // 重置查询条件，以便下一次循环
            wrapper.clear();
        }
        return inviteCode;
    }

    /**
     * 获得用户唯一ID
     * @return
     */
    public String getUserId(){
        //获取6位数 用户id
        AdminUser user = AdminUser.builder().build();
        LambdaQueryWrapper<AdminUser> wrapper = new LambdaQueryWrapper<>();
        String userId;
        while (true) {
            //生成邀请码
            userId = RandomUtils.getNumber(6);
            // 使用userId设置查询条件
            user.setUserId(userId);
            wrapper.eq(AdminUser::getUserId, userId);
            // 查询数据库中是否存在对应的用户
            AdminUser existingUser = baseMapper.selectOne(wrapper);
            // 如果不存在，则退出循环，inviteCode是唯一的
            //此处应加  userId不仅没有被使用且不是吉利号
            if (existingUser == null) {
                break;
            }
            // 重置查询条件，以便下一次循环
            wrapper.clear();
        }
        return userId;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Integer id) {
        return baseMapper.deleteById(id) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBatch(List<Integer> ids) {
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(AdminUserRequest request) {
        AdminUser entity = AdminUser.builder().build();
        BeanUtils.copyProperties(request, entity);
        return baseMapper.updateById(entity) > 0 ;
    }

    @Override
    public AdminUser getById(String id) {
        AdminUser friendUser = baseMapper.selectOne(Wrappers.lambdaQuery(AdminUser.class).eq(AdminUser::getUserId, id));
        return friendUser;
    }

    @Override
    public PageInfo<AdminUser> pageList(AdminUserRequest request) {
        Page<AdminUser> page = new Page<>(request.getPageNo(), request.getPageSize());
        LambdaQueryWrapper<AdminUser> query = this.buildWrapper(request);
        IPage<AdminUser> pageRecord = baseMapper.selectPage(page, query);
        return PageInfo.build(pageRecord);
    }


    @Override
    public List<AdminUser> list(AdminUserRequest request) {
        LambdaQueryWrapper<AdminUser> query = this.buildWrapper(request);
        return baseMapper.selectList(query);
    }

    /**
     * 用于手机号 id等查询
     * @param param
     * @return
     */
    private LambdaQueryWrapper<AdminUser> buildWrapper(AdminUserRequest param) {
        LambdaQueryWrapper<AdminUser> query = new LambdaQueryWrapper<>();
         if (StringUtils.isNotBlank(param.getUserId())){
               query.eq(AdminUser::getUserId ,param.getUserId());
        }
         if (StringUtils.isNotBlank(param.getPhone())){
               query.eq(AdminUser::getPhone ,param.getPhone());
        }
         if (StringUtils.isNotBlank(param.getNickname())){
               query.eq(AdminUser::getNickname ,param.getNickname());
        }
        if (StringUtils.isNotBlank(param.getInviteCode())){
            query.eq(AdminUser::getInviteCode ,param.getInviteCode());
        }
        return query;
    }

}
